#ifndef GRATE_UTIL_STACK_H
#define GRATE_UTIL_STACK_H

#include "grate/util/common.h"

namespace growth_rate {

// TODO(samsonov): optionally profile stack usage in the core
// library and reallocate memory in push/pop operation to save
// memory.
template <typename T>
class Stack {
 public:
  explicit Stack(size_t capacity)
    : storage_(capacity),
      capacity_(capacity),
      size_(0) { }

  bool is_empty() const { return size_ == 0; }
  const T& top() const {
    CHECK_GT(size_, 0);
    return storage_[static_cast<size_t>(size_ - 1)];
  }
  T pop() {
    CHECK_GT(size_, 0);
    return storage_[--size_];
  }
  void push(const T& item) {
    CHECK_LT(size_, capacity_);
    storage_[size_++] = item;
  }

 private:
  ScopedArray<T> storage_;
  const size_t capacity_;
  size_t size_;
};

}  // namespace growth_rate

#endif  // GRATE_UTIL_STACK_H
